package cn.js189.uqc.common;

import cn.hutool.extra.spring.SpringUtil;
import cn.js189.common.constants.Constants;
import cn.js189.uqc.mapper.ChannelInfoMapper;
import cn.js189.uqc.redis.RedisOperation;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 智慧BSS，生成请求报文基础类
 * 
 * @author Mid
 */
public abstract class RequestParamBase {
	// 日志组件
	private static final Logger LOGGER = LoggerFactory.getLogger(RequestParamBase.class);

	// appKey
	public static final String BSS_TCP_CONT_APP_KEY = "JS00000001";//JS00000001,80003,JS_DEFAULT,DEFAULT_TEST

	// 服务版本
	private static final String BSS_TCP_CONT_VERSION = "V1.0";
	// 签名字符串
	// 时间格式yyyyMMddHHmmss
	private static final String BSS_TCP_CONT_DATE_FORMAT = "yyyyMMddHHmmss";
	// tcpCont交易流水长度
	private static final int BSS_TCP_CONT_TRANS_ID_LENGTH = 18;
	// tcpCont交易流水中随机数的长度
	private static final int BSS_TCP_CONT_TRANS_ID_RANDOM_LENGTH = 4;
	// 10,000,000,000
	private static final long BSS_TCP_CONT_TEN_THOUSAND = 10000L;

	// 当前时间，格式yyyyMMddHHmmss
	private String nowString;

	/**
	 * 生成智慧BSS请求参数
	 * 
	 * @return
	 */
	public JSONObject generateContractRoot() {
		JSONObject tcpCont = generateTcpCont();
		if (null == tcpCont) {
			LOGGER.error("generate tcpCont failure");
			return null;
		}

		JSONObject svcCont = generateSvcCont();
		if (null == svcCont) {
			LOGGER.error("generate svcCont failure");
			return null;
		}

		JSONObject contractRoot = new JSONObject();
		contractRoot.put("tcpCont", tcpCont);
		contractRoot.put("svcCont", svcCont);

		JSONObject contractRootJSON = new JSONObject();
		contractRootJSON.put("contractRoot", contractRoot);
		return contractRootJSON;
	}

	/**
	 * 生成 tcpCont 会话控制信息
	 * 
	 * @return
	 */
	protected abstract JSONObject generateTcpCont();

	/**
	 * 生成 svcCont 业务内容信息
	 * 
	 * @return
	 */
	protected abstract JSONObject generateSvcCont();

	/**
	 * 生成 tcpCont 会话控制信息
	 * 
	 * @param appKey:调用方用户名，见主数据
	 * @param svcCode:提供的API接口名称
	 * @param transactionId:唯一交易流水号
	 * @return
	 */
	protected JSONObject generateTcpCont(String appKey, String svcCode, String transactionId) {
		boolean isBlankFlag = StringUtils.isBlank(appKey) || StringUtils.isBlank(svcCode);
		if (isBlankFlag) {
			LOGGER.error("appKey is blank or svcCode is blank, appKey:{}, svcCode:{}", appKey, svcCode);
			return null;
		}

		SimpleDateFormat sdf = new SimpleDateFormat(BSS_TCP_CONT_DATE_FORMAT);
		nowString = sdf.format(new Date());

		if (StringUtils.isBlank(transactionId)) {
			transactionId = generateTransId();
		} else {
			if (transactionId.length() != BSS_TCP_CONT_TRANS_ID_LENGTH) {
				LOGGER.error("transactionId is invalid, transactionId:{}", transactionId);
				return null;
			}
		}

		JSONObject tcpCont = new JSONObject();
		tcpCont.put("transactionId", transactionId);
		tcpCont.put("svcCode", svcCode);
		tcpCont.put("appKey", appKey);
		tcpCont.put("reqTime", nowString);
		//先从redis获取sign,没有查库
		RedisOperation redisOperation = SpringUtil.getBean("redisOperation");
		String eopSign = redisOperation.getForString(Constants.EOP_SIGN);
		if(StringUtils.isBlank(eopSign)){
			ChannelInfoMapper channelInfoMapper = SpringUtil.getBean("channelInfoMapper");
			eopSign = channelInfoMapper.getSignByChannelId("EOP");
		}
		tcpCont.put("sign", eopSign);
		tcpCont.put("version", BSS_TCP_CONT_VERSION);
		return tcpCont;
	}

	protected JSONObject generateTcpContNew(String appKey, String svcCode,String dstSysId ,String transactionId) {
		boolean isBlankFlag = StringUtils.isBlank(appKey) || StringUtils.isBlank(svcCode) || StringUtils.isBlank(dstSysId);
		if (isBlankFlag) {
			return null;
		}

		SimpleDateFormat sdf = new SimpleDateFormat(BSS_TCP_CONT_DATE_FORMAT);
		nowString = sdf.format(new Date());

		if (StringUtils.isBlank(transactionId)) {
			transactionId = generateTransId();
		} else {
			if (transactionId.length() != BSS_TCP_CONT_TRANS_ID_LENGTH) {
				return null;
			}
		}

		JSONObject tcpCont = new JSONObject();
		tcpCont.put("transactionId", transactionId);
		tcpCont.put("svcCode", svcCode);
		tcpCont.put("appKey", appKey);
		tcpCont.put("reqTime", nowString);
		tcpCont.put("dstSysId",dstSysId);
		//先从redis获取sign,没有查库
		RedisOperation redisOperation = SpringUtil.getBean("redisOperation");
		String eopSign = redisOperation.getForString(Constants.EOP_SIGN);
		if(StringUtils.isBlank(eopSign)){
			ChannelInfoMapper channelInfoMapper = SpringUtil.getBean("channelInfoMapper");
			eopSign = channelInfoMapper.getSignByChannelId("EOP");
		}
		tcpCont.put("sign", eopSign);
		tcpCont.put("version", BSS_TCP_CONT_VERSION);
		return tcpCont;
	}


	/**
	 * 生成 tcpCont 下的交易流水
	 * 
	 * @return
	 */
	private String generateTransId() {
		long random = (long) (Math.random() * BSS_TCP_CONT_TEN_THOUSAND);
		StringBuilder sb = new StringBuilder();
		sb.append(BSS_TCP_CONT_APP_KEY);
		sb.append(nowString);
		String randomStr = String.valueOf(random);
		int zeroPaddingLen = BSS_TCP_CONT_TRANS_ID_RANDOM_LENGTH - randomStr.length();
		if (zeroPaddingLen > 0) {
			for (int i = 0; i < zeroPaddingLen; i++) {
				sb.append("0");
			}
		}
		sb.append(randomStr);
		return sb.toString();
	}

	/**
	 * 生成 svcCont 下的认证信息
	 * 
	 * @param regionId:地区标识
	 * @param staffId:营业员标识
	 * @param staffCode:营业员工号
	 * @param channelId:渠道标识
	 * @return
	 */
	protected JSONObject generateSvcContAuthenticationInfo(String regionId, String staffId, String staffCode,
			String channelId) {
		if (StringUtils.isBlank(regionId)) {
			LOGGER.error("regionId is blank");
			return null;
		}

		JSONObject authenticationInfo = new JSONObject();
		authenticationInfo.put("regionId", regionId);
		if (StringUtils.isNotBlank(staffId)) {
			authenticationInfo.put("staffId", staffId);
		}
		if (StringUtils.isNotBlank(staffCode)) {
			authenticationInfo.put("staffCode", staffCode);
		}
		if (StringUtils.isNotBlank(channelId)) {
			authenticationInfo.put("channelId", channelId);
		}
		return authenticationInfo;
	}
}
